// Copyright 2022 The Liquigo Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package translate

import (
	config "gitee.com/west0207/liquigo/core/config"
	// . "gitee.com/west0207/liquigo/core/log"
	"strings"

	utils "gitee.com/west0207/liquigo/core/utils"

	etree "gitee.com/west0207/etree"
)

// 获取一个changeSet中的一个实体XML元素的sql语句
// dbConfig *config.DB yaml配置中的一个db配置
// entityElem *etree.Element 一个changeSet中的子实体XML元素，例如<createTable tableName="...">...</createTable>
// return (string, error) 返回该entityElem翻译后的sql语句
func GetSql(dbConfig *config.DB, entityElem *etree.Element) (string, error) {
	return getSqlByEntityElem(dbConfig, entityElem)
}

// 获取一个changeSet中的一个实体XML元素的sql语句
// dbConfig *config.DB yaml配置中的一个db配置
// entityElem *etree.Element 一个changeSet中的子实体XML元素，例如<createTable tableName="...">...</createTable>
// return (string, error) 返回该entityElem翻译后的sql语句
func getSqlByEntityElem(dbConfig *config.DB, entityElem *etree.Element) (string, error) {
	switch entityElem.Tag {
	case "createTable":
		return GetCreateTableSql(&dbConfig.DbmsName, entityElem)
	case "dropTable":
		return GetDropTableSql(&dbConfig.DbmsName, entityElem)
	case "renameTable":
		return GetRenameTableSql(&dbConfig.DbmsName, &dbConfig.DbmsVersion, entityElem)
	case "createView":
		return GetCreateViewSql(&dbConfig.DbmsName, entityElem)
	case "dropView":
		return GetDropViewSql(&dbConfig.DbmsName, entityElem)
	case "createIndex":
		return GetCreateIndexSql(&dbConfig.DbmsName, entityElem)
	case "dropIndex":
		return GetDropIndexSql(&dbConfig.DbmsName, entityElem)
	case "addColumn":
		return GetAddColumnSql(&dbConfig.DbmsName, entityElem)
	case "dropColumn":
		return GetDropColumnSql(&dbConfig.DbmsName, entityElem)
	case "renameColumn":
		return GetRenameColumnSql(&dbConfig.DbmsName, &dbConfig.DbmsVersion, entityElem)
	case "modifyDataType":
		return GetModifyDataTypeSql(&dbConfig.DbmsName, &dbConfig.DbmsVersion, entityElem)
	case "dropDefaultValue":
		return GetDropDefaultValueSql(&dbConfig.DbmsName, &dbConfig.DbmsVersion, entityElem)
	case "sqlFile":
		return GetSqlFileSql(&dbConfig.DbmsName, entityElem)
	case "sql":
		return GetSqlSql(&dbConfig.DbmsName, entityElem)
	default:
		return utils.EMPTY, nil
		// case "comment":
		// 	return GetCommentSql(&dbConfig.DbmsName, entityElem)
	}
}

// 设置属性替换值，如下是一些示例
// <createTable tableName="${tableName}" remarks="test property replace">
// <column name="birthdate" type="${date}" remarks="出生日期" />
// <column name="${createUser}" type="varchar(36)" defaultValue="${createUser.defaultValue}" />
// <constraints primaryKey="true" nullable="false" primaryKeyName="${pk}test_property_replace" />
// <constraints unique="true" nullable="false" uniqueConstraintName="${uk}user_login_account" />
// <column name="${a}_${b}_${c}" type="varchar(50)" defaultValue="${d}" remarks="multi placer" />
func SetPropertyValue(dbmsName *string, targetValue *string) {
	if !strings.Contains(*targetValue, "${") {
		return
	}
	for _, property := range config.EntryXmlConfig.Properties {
		if CheckDbms(dbmsName, &property.Dbms) {
			*targetValue = strings.Replace(*targetValue, "${"+property.Name+"}", property.Value, -1)
		}
	}
}

// 校验当前数据库类型是否满足dbms配置
// 满足则返回true，可以运行该changeSet或Property
// dbmsName *string 当前数据库类型
// dbms *string changeSet的dbms配置
func CheckDbms(dbmsName *string, dbms *string) bool {
	if *dbms == utils.EMPTY || *dbms == utils.ALL || *dbms == utils.NONE {
		return true
	}
	if strings.Contains(*dbms, utils.EXCLAMATION_MARK+*dbmsName) {
		// 包含!，例如：!mysql
		return false
	}
	if strings.Contains(*dbms, *dbmsName) {
		// 不包含!，例如：kingbase
		return true
	}
	return false
}

// 获取目标数据类型字符串
// dbmsName *string 当前数据库类型
// columnType *string 字段类型，例如: varchar(36)
// return string
func SetColumnType(dbmsName *string, columnType *string) {
	*columnType = GetDataType(dbmsName, columnType)
}
